home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / long.cpp < prev    next >
C/C++ Source or Header  |  2000-01-07  |  16KB  |  606 lines

  1. // $Id: long.cpp,v 1.12 2000/01/07 21:23:58 lord Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <iostream.h>
  12. #include "long.h"
  13. #include "double.h"
  14. //
  15. // Note that the minimum long value, (0x80000000, 0x00000000), can be represented
  16. // exactly in a double field. However, the maximum long value, (0x7FFFFFFF, 0xFFFFFFFF)
  17. // cannot. To test if the double quantity "a" fits in a long range we will test whether
  18. // or not:
  19. //         (a >= min_long) && (-a > min_long)
  20. //
  21. BaseLong::operator LongInt()
  22. {
  23.     return LongInt(HighWord(), LowWord());
  24. }
  25.  
  26. BaseLong::operator ULongInt()
  27. {
  28.     return ULongInt(HighWord(), LowWord());
  29. }
  30.  
  31. bool BaseLong::operator== (BaseLong op)
  32. {
  33.     return ((HighWord() == op.HighWord()) && (LowWord() == op.LowWord()));
  34. }
  35.  
  36. bool BaseLong::operator!= (BaseLong op)
  37. {
  38.     return ((HighWord() != op.HighWord()) || (LowWord() != op.LowWord()));
  39. }
  40.  
  41. bool BaseLong::operator!()
  42. {
  43.     return (*this == 0);
  44. }
  45.  
  46. BaseLong BaseLong::operator~()
  47. {
  48.     return BaseLong(~HighWord(), ~LowWord());
  49. }
  50.  
  51. BaseLong BaseLong::operator^ (BaseLong op)
  52. {
  53.     return BaseLong(HighWord() ^ op.HighWord(), LowWord() ^ op.LowWord());
  54. }
  55.  
  56. BaseLong& BaseLong::operator^= (BaseLong op)
  57. {
  58.     *this = *this ^ op;
  59.     return *this;
  60. }
  61.  
  62. BaseLong BaseLong::operator| (BaseLong op)
  63. {
  64.     return BaseLong(HighWord() | op.HighWord(), LowWord() | op.LowWord());
  65. }
  66.  
  67. BaseLong& BaseLong::operator|= (BaseLong op)
  68. {
  69.     *this = *this | op;
  70.     return *this;
  71. }
  72.  
  73. BaseLong BaseLong::operator& (BaseLong op)
  74. {
  75.     return BaseLong(HighWord() & op.HighWord(), LowWord() & op.LowWord());
  76. }
  77.  
  78. BaseLong& BaseLong::operator&= (BaseLong op)
  79. {
  80.     *this = *this & op;
  81.     return *this;
  82. }
  83.  
  84. bool BaseLong::operator&& (BaseLong op)
  85. {
  86.     return (*this != 0) && (op != 0);
  87. }
  88.  
  89. bool BaseLong::operator|| (BaseLong op)
  90. {
  91.     return (*this != 0) || (op != 0);
  92. }
  93.  
  94. BaseLong BaseLong::operator<< (BaseLong op)
  95. {
  96.     u4 n = op.LowWord(); // Always treat this value as positive, since negative values are not allowed
  97.  
  98.     //
  99.     // Note that this function assumes that for two 32-bit integers
  100.     // x << y, where y = 0, is well-defined and that the result is
  101.     // the value x. This is true in Ansi-C and C++ but not true in
  102.     // old versions of C (See Kernighan and Ritchie).
  103.     // Note also that in shifting a 32-bit word, if y >= 32 then the
  104.     // result is unpredictable. On Aix, xlC will produce the result 0(good!)
  105.     // whereas on windows the Microsoft compiler produces the value of x(very bad !).
  106.     // That is the reason why we have the initial special check for (n == 0).
  107.     //
  108.  
  109.     //
  110.     // gcc-2.95.1 compiler bug prevents use of this implementation.
  111.     // return (n == 0 ? *this
  112.     //                : n < 32
  113.     //                    ? BaseLong((HighWord() << n) | (LowWord() >> (32 - n)), LowWord() << n)
  114.     //                    : BaseLong(LowWord() << (n - 32), 0));
  115.     //
  116.     if (n == 0)
  117.          return *this;
  118.     else if (n < 32)
  119.          return BaseLong((HighWord() << n) | (LowWord() >> (32 - n)), LowWord() << n);
  120.     else return BaseLong(LowWord() << (n - 32), 0);
  121. }
  122.  
  123. BaseLong& BaseLong::operator<<= (BaseLong op)
  124. {
  125.     *this = *this << op;
  126.     return *this;
  127. }
  128.  
  129. BaseLong BaseLong::operator+ (BaseLong op)
  130. {
  131.     u4 ushort1 = (LowWord() & 0xFFFF) + (op.LowWord() & 0xFFFF),
  132.        ushort2 = (ushort1 >> 16) + (LowWord() >> 16) + (op.LowWord() >> 16),
  133.        ushort3 = (ushort2 >> 16) + (HighWord() & 0xFFFF) + (op.HighWord() & 0xFFFF),
  134.        ushort4 = (ushort3 >> 16) + (HighWord() >> 16) + (op.HighWord() >> 16);
  135.  
  136.     return BaseLong((ushort3 & 0xFFFF) | (ushort4 << 16), (ushort1 & 0xFFFF) | (ushort2 << 16));
  137. }
  138.  
  139. BaseLong& BaseLong::operator+= (BaseLong op)
  140. {
  141.     *this = *this + op;
  142.     return *this;
  143. }
  144.  
  145. BaseLong BaseLong::operator++ (int dummy)
  146. {
  147.     BaseLong temp = *this;
  148.     *this += 1;
  149.     return temp;
  150. }
  151.  
  152. BaseLong BaseLong::operator++ ()
  153. {
  154.     *this += 1;
  155.     return *this;
  156. }
  157.  
  158. BaseLong BaseLong::operator+ ()
  159. {
  160.     return(*this);
  161. }
  162.  
  163. BaseLong BaseLong::operator- ()
  164. {
  165.     return ~(*this) + 1;
  166. }
  167.  
  168. BaseLong BaseLong::operator- (BaseLong op)
  169. {
  170.     return *this + (-op);
  171. }
  172.  
  173. BaseLong& BaseLong::operator-= (BaseLong op)
  174. {
  175.     *this = *this - op;
  176.     return *this;
  177. }
  178.  
  179. BaseLong BaseLong::operator-- (int dummy)
  180. {
  181.     BaseLong temp = *this;
  182.     *this -= 1;
  183.     return temp;
  184. }
  185.  
  186. BaseLong BaseLong::operator-- ()
  187. {
  188.     *this -= 1;
  189.     return *this;
  190. }
  191.  
  192. BaseLong BaseLong::operator* (BaseLong op)
  193. {
  194.     u4 x0 = this -> LowWord()   & 0xFFFF,
  195.        x1 = this -> LowWord()  >> 16,
  196.        x2 = this -> HighWord()  & 0xFFFF,
  197.        x3 = this -> HighWord() >> 16,
  198.  
  199.        y0 = op.LowWord()   & 0xFFFF,
  200.        y1 = op.LowWord()  >> 16,
  201.        y2 = op.HighWord()  & 0xFFFF,
  202.        y3 = op.HighWord() >> 16;
  203.  
  204.     BaseLong result = BaseLong(0, x0 * y0),
  205.              part1  = BaseLong(0, x0 * y1);
  206.     part1  <<= (1 << 4);
  207.     result += part1;
  208.     BaseLong part2  = BaseLong(0, x0 * y2);
  209.     part2  <<= (2 << 4);
  210.     result += part2;
  211.     BaseLong part3  = BaseLong(0, x0 * y3);
  212.     part3  <<= (3 << 4);
  213.     result += part3;
  214.  
  215.     BaseLong part4  = BaseLong(0, x1 * y0);
  216.     part4  <<= (1 << 4);
  217.     result += part4;
  218.     BaseLong part5  = BaseLong(0, x1 * y1);
  219.     part5  <<= (2 << 4);
  220.     result += part5;
  221.     BaseLong part6  = BaseLong(0, x1 * y2);
  222.     part6  <<= (3 << 4);
  223.     result += part6;
  224.     BaseLong part7  = BaseLong(0, x1 * y3);
  225.     part7  <<= (4 << 4);
  226.     result += part7;
  227.  
  228.     BaseLong part8  = BaseLong(0, x2 * y0);
  229.     part8  <<= (2 << 4);
  230.     result += part8;
  231.     BaseLong part9  = BaseLong(0, x2 * y1);
  232.     part9  <<= (3 << 4);
  233.     result += part9;
  234.     BaseLong part10 = BaseLong(0, x2 * y2);
  235.     part10 <<= (4 << 4);
  236.     result += part10;
  237.     BaseLong part11 = BaseLong(0, x2 * y3);
  238.     part11 <<= (5 << 4);
  239.     result += part11;
  240.  
  241.     BaseLong part12 = BaseLong(0, x3 * y0);
  242.     part12 <<= (3 << 4);
  243.     result += part12;
  244.     BaseLong part13 = BaseLong(0, x3 * y1);
  245.     part13 <<= (4 << 4);
  246.     result += part13;
  247.     BaseLong part14 = BaseLong(0, x3 * y2);
  248.     part14 <<= (5 << 4);
  249.     result += part14;
  250.     BaseLong part15 = BaseLong(0, x3 * y3);
  251.     part15 <<= (6 << 4);
  252.     result += part15;
  253.  
  254.     return result;
  255. }
  256.  
  257. BaseLong& BaseLong::operator*= (BaseLong op)
  258. {
  259.     *this = *this * op;
  260.     return *this;
  261. }
  262.  
  263.  
  264. BaseLong::BaseLong(u4 a, u4 b)
  265. {
  266.     High() = a;
  267.     Low() = b;
  268. }
  269.  
  270. BaseLong::BaseLong(u4 a)
  271. {
  272.     High() = 0;
  273.     Low() = a;
  274. }
  275.  
  276. BaseLong::BaseLong(i4 a)
  277. {
  278.     Low() = a;
  279.     //
  280.     // Since the carry is not guaranteed to ripple, we cannot use this code.
  281.     //
  282.     //        HighWord() = a >> 31;
  283.     //
  284.     High() = (a < 0 ? 0xFFFFFFFF : 0x00000000);
  285. }
  286.  
  287.  
  288. void BaseLong::Divide(BaseLong dividend, BaseLong divisor, BaseLong "ient, BaseLong &remainder)
  289. {
  290.     u4 high = dividend.HighWord(),
  291.        low  = dividend.LowWord(),
  292.        remainder_high = 0;
  293.  
  294.     for (int i = 0; i < 32; i++)
  295.     {
  296.         remainder_high = (remainder_high << 1) | (high >> 31);
  297.         high <<= 1;
  298.         if ((ULongInt) divisor <= remainder_high)
  299.         {
  300.             high++;
  301.             remainder_high -= divisor.LowWord();
  302.         }
  303.     }
  304.  
  305.     remainder = BaseLong(0, remainder_high);
  306.  
  307.     for (int j = 0; j < 32; j++)
  308.     {
  309.         remainder <<= 1;
  310.         remainder.Low() |= (low >> 31);
  311.         low <<= 1;
  312.         if ((ULongInt) divisor <= remainder)
  313.         {
  314.             low++;
  315.             remainder -= divisor;
  316.         }
  317.     }
  318.  
  319.     quotient = BaseLong(high, low);
  320.  
  321.     return;
  322. }
  323.  
  324.  
  325. ULongInt& ULongInt::operator/= (ULongInt op)
  326. {
  327.     *this = *this / op;
  328.     return *this;
  329. }
  330.  
  331.  
  332. ULongInt ULongInt::operator/ (ULongInt op)
  333. {
  334.     BaseLong quotient,
  335.              remainder;
  336.  
  337.     Divide(*this, op, quotient, remainder);
  338.  
  339.     return quotient;
  340. }
  341.  
  342. ULongInt ULongInt::operator% (ULongInt op)
  343. {
  344.     BaseLong quotient,
  345.              remainder;
  346.  
  347.     Divide(*this, op, quotient, remainder);
  348.  
  349.     return remainder;
  350. }
  351.  
  352. ULongInt& ULongInt::operator%= (ULongInt op)
  353. {
  354.     *this = *this % op;
  355.     return *this;
  356. }
  357.  
  358.  
  359. ULongInt ULongInt::operator>> (ULongInt op)
  360. {
  361.     u4 n = op.LowWord(); // Always treat this value as positive, since negative values are not allowed
  362.  
  363.     //
  364.     // Note that this function assumes that for two 32-bit integers
  365.     // x >> y, where y = 0, is well-defined and that the result is
  366.     // the value x. This is true in Ansi-C and C++ but not true in
  367.     // old versions of C (See Kernighan and Ritchie).
  368.     // Note also that in shifting a 32-bit word, if y >= 32 then the
  369.     // result is unpredictable. On Aix, xlC will produce the result 0(good!)
  370.     // whereas on windows the Microsoft compiler produces the value of x(very bad !).
  371.     // That is the reason why we have the initial special check for (n == 0).
  372.     //
  373.  
  374.     //
  375.     // gcc-2.95.1 compiler bug prevents this implementation
  376.     // return (n == 0 ? *this
  377.     //                : n < 32
  378.     //                    ? ULongInt(HighWord() >> n, (HighWord() << (32 - n)) | (LowWord() >> n))
  379.     //                    : ULongInt(0, HighWord() >> (n - 32)));
  380.     //
  381.     if (n == 0)
  382.          return *this;
  383.     else if (n < 32)
  384.          return ULongInt(HighWord() >> n, (HighWord() << (32 - n)) | (LowWord() >> n));
  385.     else return ULongInt(0, HighWord() >> (n - 32));
  386. }
  387.  
  388. ULongInt& ULongInt::operator>>= (ULongInt op)
  389. {
  390.     *this = *this >> op;
  391.     return *this;
  392. }
  393.  
  394. bool ULongInt::operator< (ULongInt op)
  395. {
  396.     return (HighWord() == op.HighWord() ? LowWord() < op.LowWord() : HighWord() < op.HighWord());
  397. }
  398.  
  399. bool ULongInt::operator<= (ULongInt op)
  400. {
  401.     return (HighWord() == op.HighWord() ? LowWord() <= op.LowWord() : HighWord() <= op.HighWord());
  402. }
  403.  
  404. bool ULongInt::operator> (ULongInt op)
  405. {
  406.     return (HighWord() == op.HighWord() ? LowWord() > op.LowWord() : HighWord() > op.HighWord());
  407. }
  408.  
  409. bool ULongInt::operator>= (ULongInt op)
  410. {
  411.     return (HighWord() == op.HighWord() ? LowWord() >= op.LowWord() : HighWord() >= op.HighWord());
  412. }
  413.  
  414. // This conversion from double to LongInt is performed according to the rules
  415. // specified in the Java Language Specification.
  416. //
  417. LongInt::LongInt(IEEEfloat a) : BaseLong(0,0)
  418. {
  419.     IEEEdouble value = IEEEdouble(a);
  420.     LongInt lvalue = LongInt(value);
  421.     High() = lvalue.HighWord();
  422.     Low() = lvalue.LowWord();
  423.     return;
  424. }
  425.  
  426. LongInt::LongInt(IEEEdouble a) : BaseLong (0,0)
  427. {
  428.     if (a.HighWord() == 0x7fffffff && a.LowWord() == 0xffffffff) // if NaN
  429.         ; // *this is already initialized to 0
  430.     else if (a.HighWord() == 0xfff00000 && a.LowWord() == 0x00000000) // if NEGATIVE_INFINITY())
  431.         High() = 0x80000000;
  432.     else if (a.HighWord() == 0x7ff00000 && a.LowWord() == 0x00000000) // if POSITIVE_INFINITY())
  433.     {
  434.         High() = 0x7FFFFFFF;
  435.         Low()  = 0xFFFFFFFF;
  436.     }
  437.     else
  438.     {
  439.         double b = floor(a.DoubleValue() < 0.0 ? -a.DoubleValue() : a.DoubleValue()); // DSDouble
  440.  
  441.         if (b < IEEEdouble::min_long.DoubleValue())
  442.             High() = 0x80000000;
  443.         else if (-b <= IEEEdouble::min_long.DoubleValue())
  444.         {
  445.             High() = 0x7FFFFFFF;
  446.             Low()  = 0xFFFFFFFF;
  447.         }
  448.         else
  449.         {
  450.             LongInt multiplier = 1;
  451.  
  452.             while (b > 0.0)
  453.             {
  454.                 *this += (multiplier * (int) fmod(b, 10));
  455.                 b /=  10.0;
  456.                 multiplier *= 10;
  457.             }
  458.  
  459.             if (a < 0.0)
  460.                 *this = -(*this);
  461.         }
  462.     }
  463.  
  464.     return;
  465. }
  466.  
  467. LongInt LongInt::operator/ (LongInt op)
  468. {
  469.     bool negative_dividend = ((HighWord() & 0x80000000) != 0),
  470.          negative_divisor  = ((op.HighWord() & 0x80000000) != 0);
  471.  
  472.     BaseLong a = (negative_dividend ? -(*this) : +(*this)),
  473.              b = (negative_divisor  ? -(op)    : +(op)),
  474.              quotient,
  475.              remainder;
  476.  
  477.     Divide(a, b, quotient, remainder);
  478.  
  479.     return (negative_dividend ^ negative_divisor ? -quotient : quotient);
  480. }
  481.  
  482. LongInt& LongInt::operator/= (LongInt op)
  483. {
  484.     *this = *this / op;
  485.     return *this;
  486. }
  487.  
  488. LongInt LongInt::operator% (LongInt op)
  489. {
  490.     bool negative_dividend = ((HighWord() & 0x80000000) != 0),
  491.     negative_divisor  = ((op.HighWord() & 0x80000000) != 0);
  492.  
  493.     BaseLong a = (negative_dividend ? -(*this) : +(*this)),
  494.              b = (negative_divisor  ? -(op)    : +(op)),
  495.              quotient,
  496.              remainder;
  497.  
  498.     Divide(a, b, quotient, remainder);
  499.  
  500.     return (negative_dividend ? -remainder : remainder);
  501. }
  502.  
  503. LongInt& LongInt::operator%= (LongInt op)
  504. {
  505.     *this = *this % op;
  506.     return *this;
  507. }
  508.  
  509. LongInt LongInt::operator>> (LongInt op)
  510. {
  511.     u4 n = op.LowWord(); // Always treat this value as positive, since negative values are not allowed
  512.  
  513.     //
  514.     // Note that this function assumes that for two 32-bit integers
  515.     // x >> y, where y = 0, is well-defined and that the result is
  516.     // the value x. This is true in Ansi-C and C++ but not true in
  517.     // old versions of C (See Kernighan and Ritchie).
  518.     //
  519.     // Note also that in shifting a 32-bit word, if y >= 32 then the
  520.     // result is unpredictable. On Aix, xlC will produce the result 0(good!)
  521.     // whereas on windows the Microsoft compiler produces the value of x(very bad !).
  522.     // That is the reason why we have the initial special check for (n == 0).
  523.     //
  524.     // Finally, note that the right-shitfting of the HighWord is not guaranteed
  525.     // to ripple the carry bit. Whether or not the carry-bit is rippled is
  526.     // implementation-dependent. Therefore, this implementation is designed to
  527.     // shift the "long" quantity in a similar manner as the system (compiler + environement)
  528.     // used to compile it would shift a 32-bit signed integer.
  529.     //
  530.  
  531.     //
  532.     // gcc-2.95.1 compiler bug prevents use of this implementation
  533.     // return (n == 0 ? *this
  534.     //                : n < 32
  535.     //                    ? LongInt(((i4) HighWord()) >> n, (HighWord() << (32 - n)) | (LowWord() >> n))
  536.     //                    : LongInt(((i4) HighWord()) >> 31, ((i4) HighWord()) >> (n - 32)));
  537.     //
  538.     if (n == 0)
  539.          return *this;
  540.     else if (n < 32)
  541.          return LongInt(((i4) HighWord()) >> n, (HighWord() << (32 - n)) | (LowWord() >> n));
  542.     else return LongInt(((i4) HighWord()) >> 31, ((i4) HighWord()) >> (n - 32));
  543. }
  544.  
  545. LongInt& LongInt::operator>>= (LongInt op)
  546. {
  547.     *this = *this >> op;
  548.     return *this;
  549. }
  550.  
  551. bool LongInt::operator< (LongInt op)
  552. {
  553.     return (HighWord() == op.HighWord() ? LowWord() < op.LowWord() : (i4) HighWord() < (i4) op.HighWord());
  554. }
  555.  
  556. bool LongInt::operator<= (LongInt op)
  557. {
  558.     return (HighWord() == op.HighWord() ? LowWord() <= op.LowWord() : (i4) HighWord() <= (i4) op.HighWord());
  559. }
  560.  
  561. bool LongInt::operator> (LongInt op)
  562. {
  563.     return (HighWord() == op.HighWord() ? LowWord() > op.LowWord() : (i4) HighWord() > (i4) op.HighWord());
  564. }
  565.  
  566. bool LongInt::operator>= (LongInt op)
  567. {
  568.     return (HighWord() == op.HighWord() ? LowWord() >= op.LowWord() : (i4) HighWord() >= (i4) op.HighWord());
  569. }
  570.  
  571. double ULongInt::Double()
  572. {
  573.     double val = 0.0,
  574.            multiplier = 1.0;
  575.     ULongInt num = *this;
  576.  
  577.     while (num > 0)
  578.     {
  579.         val += (multiplier * (num % 10).LowWord());
  580.         num /= 10;
  581.         multiplier *= 10.0;
  582.     }
  583.  
  584.     return val;
  585. }
  586.  
  587. double LongInt::Double()
  588. {
  589.     double val;
  590.     ULongInt num;
  591.  
  592.     if (*this < 0)
  593.     {
  594.         num = -(*this);
  595.         val = -num.Double();
  596.     }
  597.     else
  598.     {
  599.         num = *this;
  600.         val = num.Double();
  601.     }
  602.  
  603.     return val;
  604. }
  605.  
  606.